/* LIBC replacement of NCNY
 * Copyright (C) 2006  Maxym V. Dilay
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

#include <system.h>
#include <stdarg.h>

void putdec(unsigned int byte)
{
	unsigned char b1;
	int b[30];
	signed int nb;
	int i=0;

	while(1){
		b1=byte%10;
		b[i]=b1;
		nb=byte/10;
		if(nb<=0){
			break;
		}
		i++;
		byte=nb;
	}

	for(nb=i+1;nb>0;nb--){
		puthexd(b[nb-1]);
	}
}

void puthexi(unsigned int dword)
{
	puthex( (dword & 0xFF000000) >>24);
	puthex( (dword & 0x00FF0000) >>16);
	puthex( (dword & 0x0000FF00) >>8);
	puthex( (dword & 0x000000FF));
}

void puthex(unsigned char byte)
{
	unsigned  char lb, rb;

	lb=byte >> 4;

	rb=byte & 0x0F;

	puthexd(lb);
	puthexd(rb);

}

void puthexd(unsigned char digit)
{
	char table[]="0123456789ABCDEF";
		putch(table[digit]);
}

void printf(const char *fmt, ...)
{
  va_list args;
  va_start(args, fmt);

  vprintf(fmt, args);

  va_end(args);
}

void vprintf(const char *fmt, va_list args)
{
	while (*fmt) {

		switch (*fmt) {
		case '%':
			fmt++;

			switch (*fmt) {
			case 's':
				puts(va_arg(args, char *));
				break;

			case 'c':
				putch(va_arg(args, unsigned int));
				break;

			case 'i':
				putdec(va_arg(args, unsigned int));
				break;

			case 'x':
				puthex(va_arg(args, unsigned int));
				break;

			case 'X':
				puthexi(va_arg(args, unsigned int));
				break;

//			case 'z':
//				textcolor(va_arg(args,unsigned int));
//				break;

			}

			break;
		default:
			putch(*fmt);
			break;
		}

		fmt++;
	}
}

void *memcpy(void *dest, const void *src, size_t count)
{
    const char *sp = (const char *)src;
    char *dp = (char *)dest;
    for(; count != 0; count--) *dp++ = *sp++;
    return dest;
}

void *memset(void *dest, char val, size_t count)
{
    char *temp = (char *)dest;
    for( ; count != 0; count--) *temp++ = val;
    return dest;
}

unsigned short *memsetw(unsigned short *dest, unsigned short val, size_t count)
{
    unsigned short *temp = (unsigned short *)dest;
    for( ; count != 0; count--) *temp++ = val;
    return dest;
}

size_t strlen(const char *str)
{
    size_t retval;
    for(retval = 0; *str != '\0'; str++) retval++;
    return retval;
}

unsigned char inportb (unsigned short _port)
{
    unsigned char rv;
    __asm__ __volatile__ ("inb %1, %0" : "=a" (rv) : "dN" (_port));
    return rv;
}

void outportb (unsigned short _port, unsigned char _data)
{
    __asm__ __volatile__ ("outb %1, %0" : : "dN" (_port), "a" (_data));
}
